//
//  Person.m
//  002-自动化归解档
//
//  Created by hzg on 2018/4/26.
//  Copyright © 2018年 tz. All rights reserved.
//

#import "Person.h"
#import <objc/message.h>

@implementation Person

/// 归档， 编码
- (void)encodeWithCoder:(NSCoder *)aCoder {
    
    /// 所有的成员变量
    /// copy create
    unsigned int count = 0;
    Ivar* ivars = class_copyIvarList([Person class], &count);
    
    /// 遍历
    for (int i = 0; i < count; i++) {
        Ivar var = ivars[i];
        const char *name = ivar_getName(var);
        NSString* key = [NSString stringWithUTF8String:name];
        
         /// kvc
        id value = [self valueForKey:key];
        
        /// 编码
        [aCoder encodeObject:value forKey:key];
    }
    
    free(ivars);
}

/// 解档， 解码
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super init]) {
        /// 所有的成员变量
        /// copy create
        unsigned int count = 0;
        Ivar* ivars = class_copyIvarList([Person class], &count);
        
        /// 遍历
        for (int i = 0; i < count; i++) {
            Ivar var = ivars[i];
            const char *name = ivar_getName(var);
            NSString* key = [NSString stringWithUTF8String:name];
            
            /// 解码
            id value = [aDecoder decodeObjectForKey:key];
            
            /// kvc
            [self setValue:value forKey:key];
        }
        
        free(ivars);
    }
    return self;
}


/// 字典转模型
- (instancetype) initWithDict:(NSDictionary*)dict {
    
    self = [super init];
    
    if (self) {
        for (NSString* key in dict.allKeys) {
            id value = dict[key];
            SEL setter = [self setterMethod:key];
            if (setter) {
                ((void (*) (id, SEL, id))objc_msgSend)(self, setter, value);
            }
        }
    }
    return self;
}

- (SEL) setterMethod:(NSString*)key {
    // setMessage
    NSString* methodName = [NSString stringWithFormat:@"set%@:", key.capitalizedString];
    
    SEL setter = NSSelectorFromString(methodName);
    if ([self respondsToSelector:setter]) {
        return setter;
    }
    return nil;
}

- (NSDictionary*) modelToDict {
    unsigned int count = 0;
    objc_property_t* properties = class_copyPropertyList([self class], &count);
    
    if (count > 0) {
        NSMutableDictionary* dict = [@{} mutableCopy];
        
        for (int i = 0; i < count; i++) {
            const void* propertyName = property_getName(properties[i]);
            NSString* name = [NSString stringWithUTF8String:propertyName];
            
            SEL sel = NSSelectorFromString(name);
            if (sel) {
               id value = ((id (*) (id, SEL))objc_msgSend)(self, sel);
                if (value) {
                    dict[name] = value;
                } else {
                    dict[name] = @"test";
                }
            }
        }
        
        return dict;
    }
    free(properties);
    return nil;
}

@end
